﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Optimization;

// ReSharper disable once CheckNamespace
namespace com.kmer {
	public class ContentVersionController {
		/// <summary>
		/// key例如：Subscribe.json
		/// </summary>
		public string Key { get; protected set; }
		/// <summary>
		/// 版本数量
		/// </summary>
		public long Count{
			get { return GetRedisClient().GetListLength("cvc:" + Key + ":hash"); }
		}

		/// <summary>
		/// 最新的版本
		/// </summary>
		public Item Last {
			get {
				if (!GetRedisClient().KeyExists("cvc:" + Key + ":hash")) return null;
				if(GetRedisClient().GetListLength("cvc:" + Key + ":hash") < 1) return null;
				var content = GetRedisClient().GetList("cvc:" + Key + ":content", -1);
				var hash = GetRedisClient().GetList("cvc:" + Key + ":hash", -1);
				var author = GetRedisClient().GetList("cvc:" + Key + ":author", -1);
				//var ticks = 0L;
				//long.TryParse(hash, NumberStyles.AllowHexSpecifier, new NumberFormatInfo(), out ticks);

				return new Item() {
					Author = author[0],
                    Content = content[0],
					Hash = hash[0]
				};
			}
		}
		/// <summary>
		/// 使用一个key初始化
		/// </summary>
		/// <param name="key"></param>
		public ContentVersionController(string key) {
			this.Key = key;
		}
		/// <summary>
		/// 获取Redislient对象
		/// </summary>
		/// <returns></returns>
		protected RedisClient GetRedisClient() {
			return new RedisClient(2);
		}
		/// <summary>
		/// 添加一个版本
		/// </summary>
		/// <param name="author"></param>
		/// <param name="content"></param>
		/// <returns></returns>
		public Item Add(string author, string content) {
			var item = new Item() {
				Author= author,
                Hash = DateTime.Now.Ticks.ToString("X"),
				Content = content
			};
			var c = GetRedisClient().AddValueToList("cvc:" + Key + ":content", item.Content);
			var h = GetRedisClient().AddValueToList("cvc:" + Key + ":hash", item.Hash);
			var a = GetRedisClient().AddValueToList("cvc:" + Key + ":author", item.Author);
			return item;
		}
		/// <summary>
		/// 添加一个版本
		/// </summary>
		/// <param name="key"></param>
		/// <param name="author"></param>
		/// <param name="content"></param>
		/// <returns></returns>
		public static Item Add(string key, string author, string content){
			return new ContentVersionController(key).Add(author,content);
		}

		/// <summary>
		/// 获取“版本”列表
		/// </summary>
		/// <param name="count">0 表示所有</param>
		/// <returns></returns>
		public IList<DateTime> GetVersions(int count = 0) {
			if (!GetRedisClient().KeyExists("cvc:" + Key + ":hash")) return null;
			var h = GetRedisClient().GetList("cvc:" + Key + ":hash", -1, -count);
			var list = new List<DateTime>();
			for (var i = 0; i < h.Length; i++) {
				var ticks = 0L;
				long.TryParse(h[i], NumberStyles.AllowHexSpecifier, new NumberFormatInfo(), out ticks);
				var d = new DateTime(ticks);
				list.Add(d);
			}
			return list;
		}

		/// <summary>
		/// 版本列表
		/// </summary>
		/// <param name="count">0 表示所有</param>
		public IEnumerable<Item> GetList(int count = 0) {
			if (!GetRedisClient().KeyExists("cvc:" + Key + ":hash")) return null;
			var c = GetRedisClient().GetList("cvc:" + Key + ":content", -count);
			var a = GetRedisClient().GetList("cvc:" + Key + ":author", -count);
			var h = GetRedisClient().GetList("cvc:" + Key + ":hash", -count);
			if (a.Length != h.Length || c.Length != h.Length) {
				return null;
			}
			return c.Select((t, i) => new Item() {
				Author = a[i],
				Content = t, Hash = h[i]
			}).ToList();
		}
		public class Item {
			/// <summary>
			/// 作者
			/// </summary>
			public string Author { get; set; }
			/// <summary>
			/// 创建时间的Tick转16进制
			/// </summary>
			public string Hash { get; set; }
			/// <summary>
			/// 创建日期
			/// </summary>
			public DateTime CreateTime {
				get {
					var ticks = 0L;
					long.TryParse(Hash, NumberStyles.AllowHexSpecifier, new NumberFormatInfo(), out ticks);
					return new DateTime(ticks);
				}
			}
			/// <summary>
			/// 内容
			/// </summary>
			public string Content { get; set; }
		}
	}
}
